Passed
Pull Request — master (#159)
by
unknown
01:49
created

FrameBuilder   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 57
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 44
dl 0
loc 57
rs 10
c 0
b 0
f 0

6 Functions

Rating   Name   Duplication   Size   Complexity  
A appendValue 0 9 1
A appendNullTerminatedValue 0 10 1
A appendNumber 0 13 3
A getBuffer 0 3 1
A appendBuffer 0 3 1
A getBufferWithPartialHeader 0 6 1
1
import * as ID3Util from "./ID3Util"
2
import { isString } from "./util"
3
import { TextEncoding } from "./definitions/Encoding"
4
5
type Value = Buffer | number | string
6
7
export class FrameBuilder {
8
    private identifier: string
9
    private buffer = Buffer.alloc(0)
10
11
    constructor(identifier: string) {
12
        this.identifier = identifier
13
    }
14
15
    appendValue(
16
        value: Value,
17
        size?: number | null,
18
        encoding: TextEncoding = TextEncoding.ISO_8859_1
19
    ) {
20
        const convertedValue = convertValue(value, encoding)
21
        this.appendBuffer(staticValueToBuffer(convertedValue, size))
22
        return this
23
    }
24
25
    appendNumber(value: number, size: number) {
26
        if (!Number.isInteger(value)) {
27
            throw new RangeError("An integer value is expected")
28
        }
29
        let hexValue = value.toString(16)
30
        if (hexValue.length % 2 !== 0) {
31
            hexValue = "0" + hexValue
32
        }
33
        this.appendBuffer(
34
            staticValueToBuffer(Buffer.from(hexValue, 'hex'), size)
35
        )
36
        return this
37
    }
38
39
    appendNullTerminatedValue(
40
        value = '',
41
        encoding: TextEncoding = TextEncoding.ISO_8859_1
42
    ) {
43
        this.appendBuffer(
44
            convertValue(value, encoding),
45
            getTerminatingMarker(encoding)
46
        )
47
        return this
48
    }
49
50
    getBuffer() {
51
        return this.buffer
52
    }
53
54
    getBufferWithPartialHeader() {
55
        const header = Buffer.alloc(10)
56
        header.write(this.identifier, 0)
57
        header.writeUInt32BE(this.buffer.length, 4)
58
        return Buffer.concat([header, this.buffer])
59
    }
60
61
    private appendBuffer(...buffers: Buffer[]) {
62
        this.buffer = Buffer.concat([this.buffer, ...buffers])
63
    }
64
}
65
66
function convertValue(
67
    value: Value,
68
    encoding: TextEncoding = TextEncoding.ISO_8859_1
69
) {
70
    if (value instanceof Buffer) {
71
        return value
72
    }
73
    if (Number.isInteger(value) || isString(value)) {
74
        return ID3Util.stringToEncodedBuffer(value.toString(), encoding)
75
    }
76
    return Buffer.alloc(0)
77
}
78
79
function staticValueToBuffer(buffer: Buffer, size?: number | null) {
80
    if (size && buffer.length < size) {
81
        return Buffer.concat([Buffer.alloc(size - buffer.length, 0x00), buffer])
82
    }
83
    return buffer
84
}
85
86
function getTerminatingMarker(encoding: TextEncoding) {
87
    if (encoding === TextEncoding.UTF_16_WITH_BOM ||
88
        encoding === TextEncoding.UTF_16_BE
89
    ) {
90
        return Buffer.alloc(2, 0x00)
91
    }
92
    return Buffer.alloc(1, 0x00)
93
}
94
95